package com.sinodata.bsm.cicp.collector.weblogic9;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: 
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-26 AM 10:07:17   liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class ServletCollector extends Collector {

    private static final Logger logger = Logger.getLogger(ServletCollector.class);

    private final Set set = new HashSet();
    private long lastTime = -1;

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();

        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
        String servletName = this.getParamMap().get("ServletName").trim();
        String contextPath = this.getParamMap().get("ContextPath").trim();
        String port = this.getParamMap().get("port").trim();

        ObjectName service;
        JMXConnector connector = null;
        MBeanServerConnection connection = null;
        try {
            connector = JmxUtil.getConnection(ip, Integer.parseInt(port));
            connection = connector.getMBeanServerConnection();
            service = new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
            Object domainConfiguration = connection.getAttribute(service, "DomainConfiguration");
            ObjectName[] appDeployments = (ObjectName[]) connection.getAttribute((ObjectName) domainConfiguration, "AppDeployments");
            QueryExp destFilter = Query.match(Query.attr("Type"), Query.value("ServletRuntime"));
            long currentTimeMillis = System.currentTimeMillis();
            if (set.isEmpty() || currentTimeMillis > lastTime + 60 * 60 * 1000) {
                set.clear();
                Set test = connection.queryNames(new ObjectName("com.bea:*"), destFilter);
                set.addAll(test);
                lastTime = currentTimeMillis;
            }
            Iterator it = set.iterator();
            while (it.hasNext()) {
                ObjectName objName = (ObjectName) it.next();
                String applicationRuntime = objName.getKeyProperty("ApplicationRuntime");
                for (int j = 0; j < appDeployments.length; j++) {
                    String applicationName = appDeployments[j].getKeyProperty("Name");
                    if (applicationName.equals(applicationRuntime)) {
                        String attributeNames[] = new String[] { "ServletName", "ContextPath", "ExecutionTimeAverage", "ExecutionTimeHigh", "ExecutionTimeLow", "ExecutionTimeTotal", "InvocationTotalCount", "PoolMaxCapacity", "ReloadTotalCount", "ServletClassName", "ServletPath", "URL" };
                        Object attrValues[] = null;
                        attrValues = JmxUtil.getAttribute(connection, objName, attributeNames);
                        if ((attrValues[0].toString().equals(servletName)) && (attrValues[1].toString().equals(contextPath))) {
                            for (int i = 2; i < attrValues.length; i++) {
                                String resultString;
                                if (attrValues[i] != null) {
                                    resultString = attrValues[i].toString();
                                } else {
                                    resultString = "N/A";
                                }
                                propValues[i - 2] = ResPropertyValue.createPropValue(resultString, propMetas[i - 2]);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("failed to collect by ServletCollector", e);
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ServletName", "ContextPath", "port" };
    }

    @Override
    public String[] getPropMeta() {
        //      return new String[] { "ExecutionTimeAverage", "ExecutionTimeHigh", "ExecutionTimeLow", "ExecutionTimeTotal", "InvocationTotalCount", "PoolMaxCapacity", "ReloadTotalCount", "ServletClassName", "ServletPath", "URL" };
        return new String[] { "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10" };
    }

}